package com.simple.gateway.center.basedata.repository;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.simple.gateway.center.basedata.common.PageUtil;
import com.simple.gateway.center.basedata.common.SimpleGatewayConstants;
import com.simple.gateway.center.basedata.mapper.ApplicationSystemMapper;
import com.simple.gateway.center.basedata.mapper.GatewayDistributionMapper;
import com.simple.gateway.center.basedata.mapper.GatewayServerDetailMapper;
import com.simple.gateway.center.basedata.mapper.GatewayServerMapper;
import com.simple.gateway.center.basedata.po.GatewayDistribution;
import com.simple.gateway.center.basedata.po.GatewayServer;
import com.simple.gateway.center.basedata.po.GatewayServerDetail;
import com.simple.gateway.center.domian.manage.bo.GatewayDistributionBO;
import com.simple.gateway.center.domian.manage.bo.GatewayServerBO;
import com.simple.gateway.center.domian.manage.bo.GatewayServerDetailBO;
import com.simple.gateway.center.domian.manage.dto.GatewayServerDTO;
import com.simple.gateway.center.domian.manage.repository.IConfigManageRepository;
import com.simple.gateway.center.web.param.GatewayServerCompositeParam;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 项目: simple-gateway-core
 * <p>
 * 功能描述:
 *
 * @author: WuChengXing
 * @create: 2023-08-07 11:37
 **/
@Component
public class ConfigManageRepository implements IConfigManageRepository {

    @Resource
    private GatewayServerMapper gatewayServerMapper;

    @Resource
    private GatewayServerDetailMapper gatewayServerDetailMapper;

    @Resource
    private GatewayDistributionMapper gatewayDistributionMapper;

    @Resource
    private ApplicationSystemMapper applicationSystemMapper;

    @Override
    public List<GatewayServerBO> queryGatewayServerList() {
        LambdaQueryWrapper<GatewayServer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GatewayServer::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        List<GatewayServer> gatewayServers = gatewayServerMapper.selectList(queryWrapper);
        List<GatewayServerBO> gatewayServerVOList = new ArrayList<>(gatewayServers.size());
        for (GatewayServer gatewayServer : gatewayServers) {
            GatewayServerBO gatewayServerBO = new GatewayServerBO();
            gatewayServerBO.setGroupId(gatewayServer.getGroupId());
            gatewayServerBO.setGroupName(gatewayServer.getGroupName());
            gatewayServerVOList.add(gatewayServerBO);
        }
        return gatewayServerVOList;
    }

    @Override
    public boolean registerGatewayServerNode(String groupId, String gatewayId, String gatewayName, String gatewayAddress, Integer status) {
        GatewayServerDetail gatewayServerDetail = new GatewayServerDetail();
        gatewayServerDetail.setGroupId(groupId);
        gatewayServerDetail.setGatewayId(gatewayId);
        gatewayServerDetail.setGatewayName(gatewayName);
        gatewayServerDetail.setGatewayAddress(gatewayAddress);
        gatewayServerDetail.setStatus(status);
        gatewayServerDetailMapper.insertGatewayServerDetail(gatewayServerDetail);
        return true;
    }

    @Override
    public GatewayServerDetailBO queryGatewayServerDetail(String gatewayId, String gatewayAddress) {
        LambdaQueryWrapper<GatewayServerDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GatewayServerDetail::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        queryWrapper.eq(GatewayServerDetail::getGatewayId, gatewayId);
        queryWrapper.eq(GatewayServerDetail::getGatewayAddress, gatewayAddress);
        GatewayServerDetail gatewayServerDetail = gatewayServerDetailMapper.selectOne(queryWrapper);
        if (null == gatewayServerDetail) {
            return null;
        }
        GatewayServerDetailBO GatewayServerDetailBO = new GatewayServerDetailBO();
        GatewayServerDetailBO.setGatewayId(gatewayServerDetail.getGatewayId());
        GatewayServerDetailBO.setGatewayName(gatewayServerDetail.getGatewayName());
        GatewayServerDetailBO.setGatewayAddress(gatewayServerDetail.getGatewayAddress());
        GatewayServerDetailBO.setStatus(gatewayServerDetail.getStatus());
        return GatewayServerDetailBO;
    }

    @Override
    public boolean updateGatewayStatus(String gatewayId, String gatewayAddress, Integer available) {
        GatewayServerDetail gatewayServerDetail = new GatewayServerDetail();
        gatewayServerDetail.setGatewayId(gatewayId);
        gatewayServerDetail.setGatewayAddress(gatewayAddress);
        gatewayServerDetail.setStatus(available);
        return gatewayServerDetailMapper.updateGatewayStatus(gatewayServerDetail);
    }

    @Override
    public List<String> queryGatewayDistributionSystemIdList(String gatewayId) {
        LambdaQueryWrapper<GatewayDistribution> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GatewayDistribution::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        queryWrapper.eq(GatewayDistribution::getGatewayId, gatewayId);
        List<GatewayDistribution> gatewayDistributions = gatewayDistributionMapper.selectList(queryWrapper);
        List<String> systemIds = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(gatewayDistributions)) {
            systemIds = gatewayDistributions.stream().map(GatewayDistribution::getSystemId).collect(Collectors.toList());
        }
        return systemIds;
    }

    @Override
    public String queryGatewayDistribution(String systemId) {
        LambdaQueryWrapper<GatewayDistribution> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GatewayDistribution::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        queryWrapper.eq(GatewayDistribution::getSystemId, systemId);
        GatewayDistribution gatewayDistribution = gatewayDistributionMapper.selectOne(queryWrapper);
        return gatewayDistribution.getGatewayId();
    }

    @Override
    public Page<GatewayServerBO> pageGatewayServer(String groupName, Integer pageNum, Integer pageSize) {
        Page<GatewayServer> buildPage = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<GatewayServer> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GatewayServer::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        if (StrUtil.isNotBlank(groupName)) {
            queryWrapper.like(GatewayServer::getGroupName, groupName);
        }
        Page<GatewayServer> gatewayServerPage = gatewayServerMapper.selectPage(buildPage, queryWrapper);
        List<GatewayServerBO> collect = gatewayServerPage.getRecords().stream().map(GatewayServerBO::do2Bo).collect(Collectors.toList());
        return PageUtil.convertPage(gatewayServerPage, collect);
    }

    @Override
    public Page<GatewayServerDetailBO> pageGatewayServerDetail(GatewayServerCompositeParam param) {
        Page<GatewayServerDetail> buildPage = new Page<>(param.getPageNum(), param.getPageSize());
        LambdaQueryWrapper<GatewayServerDetail> queryWrapper = new LambdaQueryWrapper<>();
        buildDetailSearch(queryWrapper, param);
        queryWrapper.eq(GatewayServerDetail::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        Page<GatewayServerDetail> gatewayServerDetailPage = gatewayServerDetailMapper.selectPage(buildPage, queryWrapper);
        List<GatewayServerDetailBO> collect = gatewayServerDetailPage.getRecords().stream().map(GatewayServerDetailBO::do2Bo).collect(Collectors.toList());
        return PageUtil.convertPage(gatewayServerDetailPage, collect);
    }

    @Override
    public Page<GatewayDistributionBO> pageGatewayDistribution(GatewayServerCompositeParam param) {
        Page<GatewayDistribution> buildPage = new Page<>(param.getPageNum(), param.getPageSize());
        LambdaQueryWrapper<GatewayDistribution> queryWrapper = new LambdaQueryWrapper<>();
        buildDistributionSearch(queryWrapper, param);
        queryWrapper.eq(GatewayDistribution::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        Page<GatewayDistribution> gatewayDistributionPage = gatewayDistributionMapper.selectPage(buildPage, queryWrapper);
        List<GatewayDistributionBO> collect = gatewayDistributionPage.getRecords().stream().map(GatewayDistributionBO::do2Bo).collect(Collectors.toList());
        return PageUtil.convertPage(gatewayDistributionPage, collect);
    }

    private void buildDistributionSearch(LambdaQueryWrapper<GatewayDistribution> queryWrapper,
                                         GatewayServerCompositeParam param) {
        if (StrUtil.isNotBlank(param.getGroupId())) {
            queryWrapper.like(GatewayDistribution::getGroupId, param.getGroupId());
        }

        if (StrUtil.isNotBlank(param.getGatewayId())) {
            queryWrapper.like(GatewayDistribution::getGatewayId, param.getGatewayId());
        }

        if (StrUtil.isNotBlank(param.getSystemId())) {
            queryWrapper.like(GatewayDistribution::getSystemId, param.getSystemId());
        }

        if (Objects.nonNull(param.getSystemName())) {
            queryWrapper.like(GatewayDistribution::getSystemName, param.getSystemName());
        }
    }

    private void buildDetailSearch(LambdaQueryWrapper<GatewayServerDetail> queryWrapper,
                                   GatewayServerCompositeParam param) {
        if (StrUtil.isNotBlank(param.getGatewayAddress())) {
            queryWrapper.like(GatewayServerDetail::getGatewayAddress, param.getGatewayAddress());
        }

        if (StrUtil.isNotBlank(param.getGatewayId())) {
            queryWrapper.like(GatewayServerDetail::getGatewayId, param.getGatewayId());
        }

        if (StrUtil.isNotBlank(param.getGatewayName())) {
            queryWrapper.like(GatewayServerDetail::getGatewayName, param.getGatewayName());
        }

        if (Objects.nonNull(param.getStatus())) {
            queryWrapper.eq(GatewayServerDetail::getStatus, param.getStatus());
        }
    }
}
